package edzest.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

// import java.sql.*; // *와일드문자는 가독성 측면에서 안좋다
// 어떤 클래스를 썼나 알기 힘들기 때문
// 옛날에 메모장에 하드코딩할때는 썼지만 이클립스는 컨트럴 스페이스로 자동임포트되므로
// 개별적 임포트 추천

public class J20_BookDBDAO implements J20_BookDBService {
	
	// JDBC 접속정보
	private static final String DRV = "oracle.jdbc.OracleDriver";
	private static final String URL = "jdbc:oracle:thin:@//localhost:1521/xe";
	private static final String USR = "scott";
	private static final String PWD = "TIGER";
	
	// SQL문 정의
	private static String insertSQL = 
			"insert into bookdb ( id, title, publisher, author ) values ( bookid.nextval, ?,?,?)";
	private static String selectSQL = 
			"select id, title from bookdb order by id desc"; // bookDB의 필드는 5개지만 서버의 부하를 줄이기위해 2개만 조회
	private static String selectOneSQL = 
			"select * from bookdb where id = ?";
	private static String updateSQL = 
			"update bookdb set title=?, publisher=?, author=?, regdate=sysdate where id=?" ;
	// 트랜잭션의 4가지 특성(원자성, 무결성...등)에서 무결성을 위해 날짜까지 수정, 수정을 했는데 수정한 날짜로 바뀌어야지 날짜가 그대로면 안된다
	// 프린트물에서 수정할 것 regdate=sysdate
	private static String deleteSQL = "delete from bookdb where id = ?";
	
	@Override
	public int insertBookDB(J20_BookDBVO bvo) {
		Connection conn = null;
		PreparedStatement ps = null;
		int cnt = 0;
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(insertSQL);
			// "insert into bookdb ( id, title, publisher, author ) values ( bookdb.nextval, ?,?,?)"
				ps.setString(1, bvo.getTitle()); // insertBookDB(J20_BookDBVO bvo)의 bvo
				ps.setString(2, bvo.getPublisher());
				ps.setString(3, bvo.getAuthor());
			cnt = ps.executeUpdate(); // 여기서 SQL문이 실행되고 결과를 행갯수로 반환
		}catch(Exception ex){ // 예외가 발생했을 때 처리
			ex.printStackTrace();
		}finally{ // 해당 자원을 반납
			if(ps != null)
				try{ps.close();}catch(Exception e){} // try쓴 이유: rs.close가 제대로 안되더라도 밑의 코드들을 실행하기 위해
			if(conn != null)
				try{conn.close();}catch(Exception e){}
		}
		
		return cnt;
	}

	@Override
	public String selectBookDB() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null; // 삽입,수정,삭제와 다르게 조회는 이게 추가됨!
		String result = ""; // 나중에 ArrayList로 변경예정
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(selectSQL);
			// "select id, title from bookdb order by id desc";
			rs = ps.executeQuery(); // 결과를 결과집합 rs에 저장
			
			// select문 실행 후 결과 처리
			while(rs.next()){ // 결과집합(select문 결과)에서 한행씩 데이터를 가져와서 데이터를 처리
				for(int i=1; i<=2; ++i) // 총 필드 5개지만 서버에 부하걸릴까봐 id, title 2개만 가져옴
					result += rs.getString(i) + " ";
				result += "\n";
			}
		} catch(Exception ex){
			ex.printStackTrace();
		} finally{
			if(rs != null)
				try{rs.close();}catch(Exception e){} // try쓴 이유: rs.close가 제대로 안되더라도 밑의 코드들을 실행하기 위해
			if(ps != null)
				try{ps.close();}catch(Exception e){}
			if(conn != null)
				try{conn.close();}catch(Exception e){}
		}
		
		return result;
	}

	@Override
	public String selectBookDB(String id) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		String result = "";
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(selectOneSQL);
			// "select * from bookdb where id = ?"
				ps.setString(1, id);
			rs = ps.executeQuery();
			
			while(rs.next()){
				for(int i=1; i<=5; ++i)
					result += rs.getString(i) + " ";
				result += "\n";
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			if(rs != null)
				try{rs.close();}catch(Exception e){} // try쓴 이유: rs.close가 제대로 안되더라도 밑의 코드들을 실행하기 위해
			if(ps != null)
				try{ps.close();}catch(Exception e){}
			if(conn != null)
				try{conn.close();}catch(Exception e){}
		}
		
		return result;
	}

	@Override
	public int updateBookDB(J20_BookDBVO bvo) {
		Connection conn = null;
		PreparedStatement ps = null;
		int cnt = 0;
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(updateSQL);
			// "update bookdb set title=?, publisher=?, author=?, regdate=sysdate where id=?"
				ps.setString(1, bvo.getTitle());
				ps.setString(2, bvo.getPublisher());
				ps.setString(3, bvo.getAuthor());
				ps.setString(4, bvo.getId());
			cnt = ps.executeUpdate();
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			if(ps != null)
				try{ps.close();}catch(Exception e){}
			if(conn != null)
				try{conn.close();}catch(Exception e){}
		}
		
		return cnt;
	}

	@Override
	public int deleteBookDB(String id) {
		Connection conn = null;
		PreparedStatement ps = null;
		int cnt = 0;
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(deleteSQL);
			// "delete from bookdb where id = ?"
				ps.setString(1, id);
			cnt = ps.executeUpdate();
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			if(ps != null)
				try{ps.close();}catch(Exception e){}
			if(conn != null)
				try{conn.close();}catch(Exception e){}
		}
		return cnt;
	}

}
